using System.Collections.Generic;
using System.Linq;
using EPiServer.Core;
using OpenWaves.EPiServer;
using OpenWaves.Navigation.Controls;

namespace OpenWaves.Navigation.EPiServer
{
    public class EPiNavigationViewModel<T> : INavigationViewModel<T> where T : IEPiNavigationNode<T>
    {
        private readonly PageData currentPage;
        private readonly IEnumerable<T> rootNodes;

        private PageReference[] breadcrumbs;

        public EPiNavigationViewModel(T rootNode, PageData currentPage) : this(rootNode.Children, currentPage)
        {
        }

        public EPiNavigationViewModel(IEnumerable<T> rootNodes, PageData currentPage)
        {
            this.rootNodes = rootNodes;
            this.currentPage = currentPage;
        }

        public IEnumerable<T> RootNodes
        {
            get { return this.rootNodes; }
        }

        public virtual bool IsNodeVisible(T node)
        {
            return node.IsVisibleInMenu;
        }

        private KeyValuePair<T, NavigationNodeState> lastNodeState;

        public NavigationNodeState GetNodeState(T node)
        {
            if (Equals(this.lastNodeState.Key, node) == false)
                this.lastNodeState = new KeyValuePair<T, NavigationNodeState>(node, this.GetNodeStateInternal(node));

            return this.lastNodeState.Value;
        }

        protected virtual NavigationNodeState GetNodeStateInternal(T node)
        {
            if (this.currentPage == null)
                return NavigationNodeState.Normal;

            if (Equals(this.currentPage.PageLink.ID, node.PageLink.ID))
                return NavigationNodeState.Current;

            if (this.breadcrumbs == null)
                this.breadcrumbs = this.GenerateBreadcrumbs();

            if (this.breadcrumbs.Any(b => Equals(b.ID, node.PageLink.ID)))
                return NavigationNodeState.Expanded;

            return NavigationNodeState.Normal;
        }

        protected PageReference[] GenerateBreadcrumbs()
        {
            if (this.currentPage == null)
                return new PageReference[0];

            return this.currentPage.GetAncestors().Select(a => a.PageLink).ToArray();
        }
    }
}